package ru.dadle8.service.impl.helper;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.telegram.telegrambots.meta.api.methods.AnswerCallbackQuery;
import org.telegram.telegrambots.meta.api.methods.send.SendMediaGroup;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.methods.send.SendVideo;
import org.telegram.telegrambots.meta.api.methods.updatingmessages.DeleteMessage;
import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText;
import org.telegram.telegrambots.meta.api.objects.CallbackQuery;
import org.telegram.telegrambots.meta.api.objects.InputFile;
import org.telegram.telegrambots.meta.api.objects.media.InputMedia;
import org.telegram.telegrambots.meta.api.objects.media.InputMediaVideo;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboard;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboardRemove;
import ru.dadle8.model.bot.entity.ContentMessage;
import ru.dadle8.model.bot.entity.MessageCallbackData;
import ru.dadle8.service.api.helper.MessageHelper;
import ru.dadle8.service.api.util.Utils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class MessageHelperImpl implements MessageHelper {
    private final Utils utils;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public SendMessage sendMessage(Long chatId, String text) {
        return sendMessage(chatId, text, null);
    }

    @Override
    public SendMessage sendMessage(Long chatId, String text, ReplyKeyboard replyKeyboard) {
        SendMessage outMess = new SendMessage();
        outMess.setChatId(chatId);
        outMess.setText(text);
        if (replyKeyboard != null) {
            outMess.setReplyMarkup(replyKeyboard);
        }

        return outMess;
    }

    @Override
    public SendMessage sendHideKeyboardMessage(Long chatId, String text) {
        ReplyKeyboardRemove replyKeyboardRemove = new ReplyKeyboardRemove();
        replyKeyboardRemove.setRemoveKeyboard(true);

        return sendMessage(chatId, text, replyKeyboardRemove);
    }

    @Override
    public AnswerCallbackQuery sendAnswerCallbackQuery(CallbackQuery callbackQuery) {
        AnswerCallbackQuery answerCallbackQuery = new AnswerCallbackQuery();
        answerCallbackQuery.setCallbackQueryId(callbackQuery.getId());

        return answerCallbackQuery;
    }

    @Override
    public EditMessageText sendEditMessageText(Long chatId, Integer messageId, String text) {
        return sendEditMessageText(chatId, messageId, text, null);
    }

    @Override
    public EditMessageText sendEditMessageText(Long chatId, Integer messageId, String text, InlineKeyboardMarkup inlineKeyboardMarkup) {
        EditMessageText editMessageText = new EditMessageText();
        editMessageText.setChatId(chatId);
        editMessageText.setMessageId(messageId);
        editMessageText.setText(text);
        if (inlineKeyboardMarkup != null) {
            editMessageText.setReplyMarkup(inlineKeyboardMarkup);
        }

        return editMessageText;
    }

    @Override
    public DeleteMessage sendDeleteMessage(Long chatId, Integer messageId) {
        DeleteMessage deleteMessage = new DeleteMessage();
        deleteMessage.setChatId(chatId);
        deleteMessage.setMessageId(messageId);

        return deleteMessage;
    }

    @Override
    public SendVideo sendVideo(Long chatId, ContentMessage contentMessage) {
        SendVideo sendVideo = new SendVideo();
        sendVideo.setCaption(contentMessage.getMessage());
        sendVideo.setChatId(chatId);

        InputFile inputFile = new InputFile();
        inputFile.setMedia(contentMessage.getVideos().get(0).fileId());

//        try {
//
//            URL url = new URL("https://sample-videos.com/video321/mp4/720/big_buck_bunny_720p_1mb.mp4");
//            ReadableByteChannel rbc = Channels.newChannel(url.openStream());
//            FileOutputStream fos = new FileOutputStream("/Users/dadle8/dev/SobakaSutulayaTestBot/test_file.mp4");
//            fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
//            fos.close();
//            rbc.close();
//
//
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }

//        inputFile.setMedia(new File("/Users/dadle8/dev/SobakaSutulayaTestBot/test_file.mp4"));
        sendVideo.setVideo(inputFile);

        return sendVideo;
    }

    @Override
    public List<SendMediaGroup> sendMediaGroups(Long chatId, ContentMessage contentMessage) {
        List<InputMedia> allVideoMedias = contentMessage.getVideos()
                .stream()
                .map(video -> InputMediaVideo.builder()
                        .media(video.fileId())
                        .build())
                .collect(Collectors.toList());

        // trick to see caption in message
        allVideoMedias.get(0).setCaption(contentMessage.getMessage());

        List<SendMediaGroup> sendMediaGroups = new ArrayList<>();
        List<List<InputMedia>> batches = utils.getBatches(allVideoMedias, 10);
        for (List<InputMedia> medias : batches) {
            SendMediaGroup sendMediaGroup = SendMediaGroup.builder()
                    .chatId(chatId)
                    .medias(medias)
                    .build();

            sendMediaGroups.add(sendMediaGroup);
        }

        return sendMediaGroups;
    }

    @Override
    public MessageCallbackData getMessageCallbackData(CallbackQuery callbackQuery) {
        try {
            return objectMapper.readValue(callbackQuery.getData(), MessageCallbackData.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}
